package com.nwpu.hass.serviceimpl;

import com.auth0.jwt.interfaces.Claim;
import com.nwpu.hass.domain.AuthEntity;
import com.nwpu.hass.exceptions.AuthorizeException;
import com.nwpu.hass.service.RedisService;
import com.nwpu.hass.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <h3>hass</h3>
 * <p>Redis服务实现</p>
 *
 * @author : Qin
 * @date : 2021-01-07 10:40
 **/
@Service
@Slf4j
public class RedisServiceImpl implements RedisService {

    @Value("${jwt_expire_time}")
    private Long expire_time;

    @Resource
    private RedisTemplate<String,String> redisTemplate;


    /**
     * 验证当前token是否超时失效
     * @param token 用户携带的token
     * @return 失效还是未失效
     */
    @Override
    public Boolean verifyToken(String token){
        if (StringUtils.isBlank(token)) {
            log.warn("token为空");
            throw new AuthorizeException("token为空");
        }
        String secret = null;
        try {
            secret = redisTemplate.opsForValue().get(token);
        }catch (Exception e){
            log.info("token已被redis中删除");
        }
        log.info("token经过一层验证，即redis中存在token");
        return secret != null;
    }
    @Override
    public void set(String token, String secret) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        ValueOperations<String,String> vo = redisTemplate.opsForValue();
        // 方便测试1000个小时后redis中的键值对过期
        vo.set(token,secret);
        redisTemplate.expire(token, expire_time, TimeUnit.HOURS);
    }

    @Override
    public AuthEntity getAuth(String token) {
        if (verifyToken(token)){
            String secret = redisTemplate.opsForValue().get(token);
            Map<String, Claim> map = JwtUtils.decodeJwt(token,secret);
            AuthEntity authEntity = AuthEntity.Map2Info(map);
            return authEntity;

        }
        return null;
    }

    @Override
    public Long getUserId(String token) {
        return getAuth(token).getUserId();
    }
}
